home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGofer 0.22d / MacGofer Sources / twospace.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-06  |  5.0 KB  |  169 lines  |  [TEXT/MPS ]

  1. /* --------------------------------------------------------------------------
  2.  * twospace.c:  Copyright (c) Mark P Jones 1991-1993.   All rights reserved.
  3.  *              See goferite.h for details and conditions of use etc...
  4.  *              Gofer version 2.28 January 1993
  5.  *
  6.  * Two space copying GC, optionally used for gofc runtime system.
  7.  * ------------------------------------------------------------------------*/
  8.  
  9. /* --------------------------------------------------------------------------
  10.  * Simple twospace copying collector:
  11.  * ------------------------------------------------------------------------*/
  12.  
  13. static Void   heapInit        Args((Void));
  14. static Void   markPhase        Args((Void));
  15. static Cell   forward        Args((Cell));
  16. static Cell   copyCell        Args((Cell));
  17.  
  18. Int     heapSize = DEFAULTHEAP;        /* number of cells in heap       */
  19. static  Heap space1,space2;        /* the two heap spaces           */
  20. #ifndef GLOBALcar
  21. Heap    from;                /* (top of) current from space       */
  22. #endif
  23. static  Heap to;            /* (top of) current to space       */
  24. #ifndef GLOBALcdr
  25. Cell    hp;                /* current heap pointer           */
  26. #endif
  27. static  Bool fileUsed[NUM_FILES];    /* file in use flags           */
  28. #define mark(c)  c=forward(c)        /* mark graph and save new pointer */
  29.  
  30. static Void heapInit() {        /* initialise heap storage       */
  31.     space1 = (Heap)(farCalloc(heapSize,sizeof(Cell)));
  32.     space2 = (Heap)(farCalloc(heapSize,sizeof(Cell)));
  33.     if (space1==(Heap)0 || space2==(Heap)0)
  34.     abandon("Cannot allocate heap storage");
  35.     from = space1 + heapSize;
  36.     to   = space2 + heapSize;
  37.     hp   = -heapSize-1;
  38. }
  39.  
  40. #if  !INLINE_ALLOC            /* allocation (not inlined) gives  */
  41. Cell pair(l,r)                /* smaller object code size, but   */
  42. Cell l,r; {                /* with a small hit on speed.       */
  43.     from[++hp] = l;
  44.     from[++hp] = r;
  45.     return (hp-1);
  46. }
  47. #endif
  48.  
  49. Void garbageCollect() {            /* garbage collector           */
  50.     register Cell toIn = -heapSize-1;
  51.     Heap swap;
  52.     Int  i;
  53.     hp = toIn;
  54.  
  55.     for (i=0; i<NUM_FILES; ++i)        /* assume all files need collection*/
  56.     fileUsed[i] = FALSE;
  57.  
  58.     markPhase();            /* mark all cells in use       */
  59.  
  60.     while (toIn<hp) {            /* use tospace as a queue to copy  */
  61.     Cell tag = to[++toIn];        /* the whole graph currently in use*/
  62.  
  63.     if (isPair(tag)) {        /* must be application node       */
  64.         to[toIn] = forward(tag);
  65.         ++toIn;            /* to another cell           */
  66.         to[toIn] = forward(to[toIn]);
  67.     }
  68.         else if (tag>MAXBOXTAG) {    /* application of unboxed value       */
  69.         ++toIn;            /* to another cell           */
  70.         to[toIn] = forward(to[toIn]);
  71.     }
  72.     else                /* tagged cell - value already       */
  73.         ++toIn;            /*          copied across       */
  74.     }
  75.     if (hp+1000>=0)
  76.     abandon("Garbage collection fails to reclaim sufficient space");
  77.  
  78.     for (i=0; i<NUM_FILES; ++i)        /* close all files no longer in use*/
  79.     if (!fileUsed[i])
  80.         closeFile(i);
  81.  
  82.     swap = from;            /* exchange tospace and fromspace  */
  83.     from = to;
  84.     to   = swap;
  85. }
  86.  
  87. static Void markPhase() {        /* mark phase of garbage collector */
  88.     StackPtr sp1;
  89.     Int         i;
  90.  
  91.     stackLoop(sp1)            /* mark nodes on stack           */
  92.     mark(*sp1);
  93.     for (i=0; i<num_scs; i++)        /* mark supercombinator nodes       */
  94.     mark(sc[i]);
  95.     for (i=0; i<num_cdicts; i++)        /* mark dictionary entries       */
  96.     mark(dict[i]);
  97.     for (i=0; i<NUM_CHARS; ++i)        /* mark character conses       */
  98.     mark(consCharArray[i]);
  99.     mark(resps);            /* mark responses           */
  100.     primMark();                /* mark primitives           */
  101. }
  102.  
  103. static Cell forward(c)            /* find forwarding location of cell*/
  104. Cell c; {
  105.     if (isPair(c)) {            /* only pairs need be forwarded       */
  106.     Cell tag = fst(c);
  107.     if (tag==INDIRECT) {        /* short out indirection nodes       */
  108.         Cell back = mkCfun(0);
  109.         do {
  110.         fst(c) = INDIRECT1;
  111.         tag    = snd(c);
  112.         snd(c) = back;
  113.         back   = c;
  114.         c      = tag;
  115.         if (!isPair(c))
  116.             break;
  117.         tag    = fst(c);
  118.         } while (tag==INDIRECT);
  119.  
  120.         if (isPair(c)) {        /* a specialised form of forward() */
  121.         if (tag==INDIRECT1)
  122.             c = primBlackHole;
  123.         else if (tag==FORWARD)
  124.             c = snd(c);
  125.         else {
  126.             if (tag==FILECELL)
  127.             fileUsed[snd(c)] = TRUE;
  128.             c = copyCell(c);
  129.         }
  130.         }
  131.     
  132.         while (isPair(back)) {    /* update all indirections       */
  133.         tag      = snd(back);
  134.         fst(back) = FORWARD;
  135.         snd(back) = c;
  136.         back      = tag;
  137.         }
  138.         return c;
  139.     }
  140.     else if (tag==FORWARD)        /* previously forwarded cell       */
  141.         return snd(c);
  142.     else {                /* pair to be forwarded           */
  143.         if (tag==FILECELL)
  144.         fileUsed[snd(c)] = TRUE;
  145.         return copyCell(c);
  146.     }
  147.     }
  148.     return c;
  149. }
  150.  
  151. static Cell copyCell(c)            /* copy pair fromspace --> tospace */
  152. Cell c; {
  153. #if SMALL_GOFER
  154.     to[++hp]  = from[c];        /* not worth the trouble of a reg  */
  155.     from[c]   = FORWARD;        /* assignment for far pointers       */
  156.     to[++hp]  = from[c+1];
  157.     from[c+1] = hp-1;
  158.     return hp-1;
  159. #else
  160.     register Cell *fp = from+c;
  161.     to[++hp] = *fp;            /* don't need to check for heap       */
  162.     *fp++    = FORWARD;            /* overflow since no halfspace can */
  163.     to[++hp] = *fp;            /* be bigger that the other!       */
  164.     return (*fp = hp-1);
  165. #endif
  166. }
  167.  
  168. /*-------------------------------------------------------------------------*/
  169.